//
//  CZHomeViewController.swift
//  iOSWeibo10
//
//  Created by itcast on 16/5/9.
//  Copyright © 2016年 itcast. All rights reserved.
//

import UIKit

import SVPullToRefresh

// 打通数据 -> 获取服务器的数据,看看有没有什么问题
class CZHomeViewController: CZBaseTableViewController {
    
    // MARK: - 属性
    private let reuseIdentifier = "cell"
    
    private let TipLabelHeight: CGFloat = 44
    
    /// 要显示的微博数据
    var statuses: [CZStatus]? {
        didSet {    // 模型数据改变了
            CZPrint(items: "当前总共有 \(statuses?.count) 条微博")
            self.tableView.reloadData()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 没有登录就不要执行后面的代码
        if !CZUserAccountViewModel.sharedInstance.isUserLogin {
            return
        }
        
        setupNavigationBar()
        
        prepareTableView()
        
        // 添加下拉刷新的提示
//        tableView.addSubview(tipLabel)
//        UIApplication.sharedApplication().keyWindow?.addSubview(tipLabel)
        navigationController?.navigationBar.insertSubview(tipLabel, atIndex: 0)
    }
    
    /**
     设置tableView相关的内容
     */
    private func prepareTableView() {
        // 注册cell,如果使用自己的cell就注册自定义的cell,如果使用系统的cell就注册系统的cell
        tableView.registerClass(CZStatusCell.self, forCellReuseIdentifier: reuseIdentifier)
        
        // 设置cell预估行高
        tableView.estimatedRowHeight = 200  // 667
        // 根据cell的约束自动计算行高, 测量contentView的高度
        tableView.rowHeight = UITableViewAutomaticDimension
        
        // 取消tableViewcell的分隔线
        tableView.separatorStyle = UITableViewCellSeparatorStyle.None
        
        // MARK: - 下拉刷新控件相关
        // 添加下拉刷新控件到tableView
        tableView.addSubview(pullDownToRefreshControl)
        
        // 监听下拉刷新控件进入刷新状态
        pullDownToRefreshControl.pullDownToRefreshCallback = { () -> () in
            self.loadNewStatus()
        }
        
        /// 当进入程序显示homeViewControll就主动进入刷新状态
        pullDownToRefreshControl.beginRefreshing()
        
//        // MARK: - 上拉加载更多相关
//        /// 调用addInfiniteScrollingWithActionHandler方法传入闭包,就会有上拉加载的菊花
//        tableView.addInfiniteScrollingWithActionHandler { () -> Void in
//            // 加载比当前最小ID还要小的ID微博
//            self.loadMoreStatus()
//        }
    }
    
    /**
     上拉加载更多的微博
     */
    private func loadMoreStatus() {
        // 获取最小微博的ID,整个数组中最后那条微博就是ID最小的微博
        let max_id = self.statuses?.last?.id ?? 0
        CZStatusViewModel.sharedInstance.loadStatus(0, max_id: max_id) { (statuses, error) -> () in
            // 上拉加载控件停止动画
            self.tableView.infiniteScrollingView.stopAnimating()
            
            if error != nil {
                CZPrint(items: "上拉加载微博出错了: \(error)")
                return
            }
            
            let count = statuses?.count ?? 0
            if count == 0 {
                CZPrint(items: "上拉没有加载到微博数据")
                return
            }
            CZPrint(items: "上拉加载了 \(count) 条微博")
            
            // 将获取到的微博数据添加到现有数据的后面
            self.statuses = self.statuses! + statuses!
        }
    }
    
    // MARK: - 获取微博方法
    /// 获取新的微博数据
    private func loadNewStatus() {
        // 数组里面最前那条微博ID最大,since_id = 0 获取最新20条
        // first获取第一个元素 CZStatus
        let since_id = self.statuses?.first?.id ?? 0
        CZStatusViewModel.sharedInstance.loadStatus(since_id, max_id: 0) { (statuses, error) -> () in
            self.pullDownToRefreshControl.endRefreshing()
            
            if error != nil {
                CZPrint(items: "加载微博出错了: \(error)")
                return
            }
            
            let count = statuses?.count ?? 0
            CZPrint(items: "获取到了 \(count) 条微博数据")
            
            // 判断是下拉刷新才显示
            if since_id > 0 {
                self.showTipLabel(count)
            }
            
            if count == 0 {
                // 没有加载到微博数据,直接返回
                return
            }
            
            // 获取到了微博数据
            // 判断是下拉刷新新的微博,还是加载20微博
            if since_id == 0 {
                // 加载20条微博, 直接显示这20条数据
                self.statuses = statuses
                
                // 第一次加载了微博数据后,才可以上拉加载更多
                // MARK: - 上拉加载更多相关
                /// 调用addInfiniteScrollingWithActionHandler方法传入闭包,就会有上拉加载的菊花
                self.tableView.addInfiniteScrollingWithActionHandler { () -> Void in
                    // 加载比当前最小ID还要小的ID微博
                    self.loadMoreStatus()
                }
            } else {
                // since_id加载比某条新的微博,下拉刷新
                // 获取到的新的微博数组添加到现有数组的前面
                self.statuses = statuses! + self.statuses!
            }
        }
    }
    
    /// 设置下拉刷新的提示label
    private func showTipLabel(count: Int) {
        let text = count == 0 ? "没有新的微博" : "加载了 \(count) 条新微博"
        
        tipLabel.text = text
        
        // 当动画还没有回去,又指定动画会出现动画叠加
        // 在做动画之前,将之前的动画移除
        // UIView动画最终也是核心动画
        let anim = self.tipLabel.layer.animationKeys() // 获取在layer上的所有核心动画
        // 如果找到了动画说明有动画还没做完,移除它
        if anim != nil {
            CZPrint(items: "之前有动画没做完,移除: \(anim)")
            self.tipLabel.layer.removeAllAnimations()
        }
        
        let duration = 0.75
        UIView.animateWithDuration(duration, animations: { () -> Void in
            self.tipLabel.frame.origin.y = self.TipLabelHeight
            }) { (_) -> Void in
                // 动画完了,还要做回去的动画,延迟回去的动画
                UIView.animateKeyframesWithDuration(duration, delay: 1, options: UIViewKeyframeAnimationOptions(rawValue: 0), animations: { () -> Void in
                    self.tipLabel.frame.origin.y = -64
                    }, completion: nil)
        }
    }
    
    // 设置导航栏
    private func setupNavigationBar() {
        // 方案4
        navigationItem.leftBarButtonItem = UIBarButtonItem(imageName: "navigationbar_friendsearch", target: self, action: "didClickFriendsearch")
        navigationItem.rightBarButtonItem = UIBarButtonItem(imageName: "navigationbar_pop", target: self, action: "didClickPop")
        
        // 获取用户的名称
        // 测试
//        CZUserAccountViewModel.sharedInstance.userAccount?.screen_name = nil
        let name = CZUserAccountViewModel.sharedInstance.userAccount?.screen_name ?? "未知名称"
        // 设置首页titleView
        let button = CZHomeTitleButton()
        button.setTitle(name, forState: UIControlState.Normal)
        button.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
        button.titleLabel?.font = UIFont.systemFontOfSize(16)
        button.setImage(UIImage(named: "navigationbar_arrow_down"), forState: UIControlState.Normal)
        button.addTarget(self, action: "didClickTitlView:", forControlEvents: UIControlEvents.TouchUpInside)
        
        button.sizeToFit()
        
        navigationItem.titleView = button
    }
    
    // MARK: 按钮点击事件
    func didClickTitlView(button: UIButton) {
        // 三角形旋转依靠button.selected这个属性来确定
        // 1.修改按钮的状态
        button.selected = !button.selected

        
        UIView.animateWithDuration(0.25) { () -> Void in
            let transfrom = button.selected ? CGAffineTransformMakeRotation(CGFloat(M_PI - 0.001)) : CGAffineTransformIdentity
            button.imageView?.transform = transfrom
        }
    }
    
    func didClickFriendsearch() {
        CZPrint(items: "点击了左边")
    }
    
    func didClickPop() {
        CZPrint(items: "点击了右边")
        
        // 加载本地json数据
        let file = NSBundle.mainBundle().pathForResource("statuses", ofType: "json")!
        let data = NSData(contentsOfFile: file)!
        let json = try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0))
        CZPrint(items: "解析本地数据: \(json)")
    }
    
    // MARK: - 懒加载
    /// 下拉刷新控件
    private lazy var pullDownToRefreshControl: CZPullDownToRefreshControl = CZPullDownToRefreshControl()
    
    /// 下拉提示的label
    private lazy var tipLabel: UILabel = {
        let label = UILabel()
        
        // 设置
        label.backgroundColor = UIColor.orangeColor()
        label.font = UIFont.systemFontOfSize(18)
        label.textColor = UIColor.whiteColor()
        label.textAlignment = NSTextAlignment.Center
        
        label.frame = CGRect(x: 0, y: -20 - self.TipLabelHeight, width: UIScreen.mainScreen().bounds.width, height: self.TipLabelHeight)
        
        return label
    }()
}

// 扩展CZHomeViewController, talbeView显示数据
extension CZHomeViewController {
    /*
        tableView优化:
            1.cell复用: 使用tableView的.deque...方法先去缓存池中找
            2.cell里面要显示网络图片使用SDWebImage,有缓存,2异步下载
            3.cellForRowAtIndexPath里面.
                *.尽量不要做耗时的操作,如果避免不了使用子线程来处理
                *.从本地加载图片,contentOfFile,会在主线程,读文件是本来就是耗时的操作,一进入界面就先用子线程去本地加载图片 NSCache
                *.不要在cellForRowAtIndexPath里面写文件
                *.cellForRowAtIndexPath里面不要去创建和删除view,最好是先懒加载好,显示就view.hidden = false,不要显示view.hidden = true
            4.tableView滚动的时候停下gif.视频
            5.view的透明层,能不设置就不设置
            6.view尽量不要设置transform
            7.视图层次结构不要太多
            8.cell高度不同的时候,最好只算一次,然后缓存起来,下次直接使用缓存的高度
            9.尽量不要图层圆角,1.将图片画成圆角2.让美工提供一张中间是圆角透明的图片遮在图片上面
            10.尽量不要去设置图层阴影,会造成额外的开销(离屏渲染) 离屏渲染:GPU在还没有渲染到屏幕上之前要多做的一次渲染
            * 利用工具来查看
    
    */
    // 让tableView的cell高度根据自动约束来自己确定
//    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
//        // 先判断有没有缓存的行高
//        // 获取到indexPath.row的模型
//        let status = self.statuses![indexPath.row]
//        
//        if let rowHeight = status.rowHeight {
//            // 有缓存的行高
////            CZPrint(items: "有缓存的行高: \(rowHeight), row: \(indexPath.row)")
//            return rowHeight
//        }
//        
//        // 能到下面来没有缓存的行高
//        // 计算行高
//        // 拿一个cell,把模型给cell,cell里面的子控件内容会根据模型设置,cell的子控件的位置和大小会根据模型的内容重新更新.这个cell并不会去显示,最终我们要拿到的是cell.contentView的高度
//        // 使用tableView dequeueReusableCellWithIdentifier:forIndexPath他会调用tableView:heightForRowAtIndexPath
////        let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath)
//        let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as! CZStatusCell
//        cell.status = status
//        
//        // 获取高度
//        let rowHeight = cell.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
//        // 计算好了应该要缓存起来,高度和模型相关,高度放模型里面最合适
//        status.rowHeight = rowHeight
////        CZPrint(items: "计算行高: \(rowHeight) row: \(indexPath.row)")
//        return rowHeight
//    }
    
    /// 返回cell的数量
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // ?? 前面的可选没有值就使用??后面的值
        // ?? 前面的可选有值只用??前面的可选,进行后续的操作
        return statuses?.count ?? 0
    }
    
    /// cell显示内容
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        // 根据identifier去缓存池中查找,缓存池中有就返回一个cell,缓存池中没有,使用注册的cell类型来创建cell
//        let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier, forIndexPath: indexPath) as! CZStatusCell
        // 减少行高的调用次数
        let cell = tableView.dequeueReusableCellWithIdentifier(reuseIdentifier) as! CZStatusCell
        
        // 获取到对应的模型
        let status = self.statuses![indexPath.row]
        
        // 1.数据源给cell设置对应的模型
        cell.status = status
        
//        if true {
//            // 添加一个view
//        } else {
//            // 删除刚才添加的view
//        }
        
//        dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
//            for i in 0..<10000 {
//                CZPrint(items: "i : \(i)")
//            }
//        }
        
        return cell
    }
    
    /// 通过代理方法来监听tableView的contentOffest.Y改变
    /// 不要通过代理方式来监听scroollView的contentOffest.Y,在这里监听,控制器和下拉刷新控件依赖很严重
//    override func scrollViewDidScroll(scrollView: UIScrollView) {
//        CZPrint(items: "我在控制器里面通过代理监听scrollView的contentOffest.y: \(scrollView.contentOffset.y)")
//    }
}